package com.maybach.web.framework;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.ConfigurablePropertyAccessor;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.util.Assert;
import org.springframework.validation.AbstractBindingResult;
import org.springframework.validation.BindingResult;
import org.springframework.validation.DataBinder;

import java.io.Serializable;

/**
 * Created by houenxun on 16/1/13.
 * 可序列化的的bindingResult
 */
public class SerializableBindingResult extends AbstractBindingResult implements  Serializable{
    private static final long serialVersionUID = 1L;

    protected  Object target ;
    private  boolean autoGrowNestedPaths = true;

    private  int autoGrowCollectionLimit = DataBinder.DEFAULT_AUTO_GROW_COLLECTION_LIMIT;
    private transient BeanWrapper beanWrapper;


    public SerializableBindingResult(BindingResult bindingResult){
        super(bindingResult.getObjectName());
        this.addAllErrors(bindingResult);
        this.setNestedPath(bindingResult.getNestedPath());
        this.target = bindingResult.getTarget();
        /*if(bindingResult instanceof BeanPropertyBindingResult){
            BeanPropertyBindingResult beanPropertyBindingResult = (BeanPropertyBindingResult)bindingResult;
            beanPropertyBindingResult.
        }
        this.autoGrowNestedPaths = autoGrowNestedPaths;
        this.autoGrowCollectionLimit = autoGrowCollectionLimit;*/
    }

    @Override
    public Object getTarget() {
        return target;
    }

    /**
     * Fetches the field value from the PropertyAccessor.
     * @see #getPropertyAccessor()
     */
    @Override
    protected Object getActualFieldValue(String field) {
        return getPropertyAccessor().getPropertyValue(field);
    }
    public final ConfigurablePropertyAccessor getPropertyAccessor() {
        if (this.beanWrapper == null) {
            this.beanWrapper = createBeanWrapper();
            this.beanWrapper.setExtractOldValueForEditor(true);
            this.beanWrapper.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
            this.beanWrapper.setAutoGrowCollectionLimit(this.autoGrowCollectionLimit);
        }
        return this.beanWrapper;
    }

    /**
     * Create a new {@link BeanWrapper} for the underlying target object.
     * @see #getTarget()
     */
    protected BeanWrapper createBeanWrapper() {
        Assert.state(this.target != null, "Cannot access properties on null bean instance '" + getObjectName() + "'!");
        return PropertyAccessorFactory.forBeanPropertyAccess(this.target);
    }
}
